var stats = new Stats(),
    sts = stats.domElement.style;
sts.position = 'absolute';
sts.top = '0px';
sts.right = '0px';
document.body.appendChild(stats.domElement);

var c = document.getElementById('c');
var ctx = c.getContext('2d');
var w, h, cx, cy, mx, my; //宽高 和 中心点 位置
var maxStrength = 3000;
var isMouseMoved = false;
var follower = {};
handleWindowResize(); //初始化

/**
 * 粒子类
 */
function Particle(x, y) {
    this.x = x;
    this.y = y;
    this.ox = x;
    this.oy = y;
    this.an = Math.random() * (Math.PI * 2);
    this.san = Math.random() * .1;
    this.alpha = Math.random();
    this.r = 1 + Math.random() * 4;
    if(Math.random() * 10 < 5 && this.alpha < .2) {
        this.r = Math.random() * 20;
    }
    this.br = this.r;
}
//设置粒子类原型对象
Particle.prototype = {
    update: function(ff) {
        var dx = this.x - ff.x;
        var dy = this.y - ff.y;
        var d = Math.sqrt(dx * dx + dy * dy);
        var a = Math.atan2(dy, dx);
        var f = maxStrength / d;
        this.x += (this.ox - this.x) * .1;
        this.y += (this.oy - this.y) * .1;
        this.x += Math.cos(a) * f;
        this.y += Math.sin(a) * f;
        if(this.alpha < .2) {
            this.r = this.br + Math.cos(this.an) * (this.br * .8);
            this.an += this.san;
        }
    },
    render: function(ctx) {
        ctx.fillStyle = 'rgba(255, 255, 255, '+ this.alpha +')';
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2);
        ctx.fill();
    }
};

//构建粒子数组
var particles = [];
var count = 500;
var particle;
for(var i = 0; i < count; i += 1) {
    particle = new Particle(Math.random() * w, Math.random() * h);
    particles.push(particle);
}

//动画函数
function animate() {
    //帧动画
    requestAnimationFrame(animate);
    stats.update();

    //清除背景
    ctx.clearRect(0, 0, w, h);

    follower.r += (follower.tr - follower.r) * .1;

    if(!isMouseMoved) { //鼠标没有移动时
        follower.vx += Math.random() * 2 - 1;
        follower.vy += Math.random() * 2 - 1;
        follower.x += follower.vx;
        follower.y += follower.vy;
        if(Math.abs(follower.vx) > 10) {
            follower.vx = 0;
        }
        if(Math.abs(follower.vy) > 10) {
            follower.vy = 0;
        }
        if(follower.x < 0) {
            follower.x = 0;
            follower.vx *= -1;
        }
        if(follower.x > w) {
            follower.x = w;
            follower.vx *= -1;
        }
        if(follower.y < 0) {
            follower.y = 0;
            follower.vy *= -1;
        }
        if(follower.y > h) {
            follower.y = h;
            follower.vy *= -1;
        }
    } else {
        follower.x += (mx - follower.x) * .1;
        follower.y += (my - follower.y) * .1;
    }

    for(var i = 0, len = particles.length; i < len; i += 1) {
        var particle = particles[i];
        particle.update(follower);
        particle.render(ctx);
    }

    for(var i = 0; i < particles.length; i += 1) {
        for(var j = i + 1; j < particles.length; j += 1) {
            var p1 = particles[i];
            var p2 = particles[j];
            var dx = p1.x - p2.x;
            var dy = p1.y - p2.y;
            var d = Math.sqrt(dx * dx + dy * dy);
            if(d < 40) {
                ctx.strokeStyle = 'rgba(255, 255, 255, '+ p1.alpha +')';
                ctx.beginPath();
                ctx.moveTo(p1.x, p1.y);
                ctx.lineTo(p2.x, p2.y);
                ctx.stroke();
            }
        }
    }

    ctx.save();
    ctx.strokeStyle = 'rgba(0, 0, 0, .5)';
    ctx.fillStyle = 'red';
    ctx.lineWidth = 4;
    ctx.beginPath();
    ctx.arc(follower.x, follower.y, follower.r, 0, Math.PI * 2);
    ctx.closePath();
    ctx.stroke();
    ctx.fill();
    ctx.restore();
}

//窗口重置事件处理函数
function handleWindowResize(e) {
    w = c.width = window.innerWidth * window.devicePixelRatio;
    h = c.height = window.innerHeight * window.devicePixelRatio;
    cx = w / 2;
    cy = h / 2;
    follower = {
        x: cx,
        y: cy,
        vx: 0,
        vy: 0,
        r: 20,
        tr: 20
    }
}

//处理在canvas对象内鼠标移动事件
function handleMouseMoveEnterC(e) {
    var rect = c.getBoundingClientRect();
    mx = e.clientX - rect.left;
    my = e.clientY - rect.top;
    isMouseMoved = true;
}

//事件绑定
window.addEventListener('resize', handleWindowResize);

c.addEventListener('mousemove', handleMouseMoveEnterC);

//启动
animate();